
export default function Draw(options){
  const statusConfig = {
    IDLE: 0, // 闲置即正常状态   // 矩形框被拖拽的三种状态
    DRAG_START: 1,// 开始拖拽
    DRAGING: 2, // 拖拽中 ,
    MOVE_START: 3, // 画布移动开始的状态 因为画布移动也是一个持续的过程 所以 也要记录状态
    MOVING: 4
  }
  // canvas 画布信息存存储对象
  const canvasInfo = {
    status: statusConfig.IDLE,
    dragTarget: null,
    lastEvtPos:{ x: null, y: null }, // 计算上次鼠标位置 为了确定这次基于上次的偏移量是多少  以便设置阈值 大于之后才认为是拖动 而不是误触或者误点击
    offsetEvtPos: { x: null, y: null }, // 记录鼠标的实时位置相对于画布的 以便形状移动可以相对于鼠标的位置移动 而不是首先将图形的开始位置设置为鼠标当前的位置
    offseteMouseEvtPos:  { x: null, y: null },// 解决画布移动造成抖动偏移的问题
    offset:{ x:0, y:0 },  // 画布放缩后会出现的偏移 画布的偏移
    scale: 1, // 画布当前的缩放
    scaleStep:0.1,
    maxScale: 8,
    minScale: 1,
    openDraw:false,
    dynamicInfo:{ x: null, y: null, w: 0, h: 0},// 动态绘制的坐标信息
  }
    // 画布不会记录上面画的内容 所以要找内容存储 画布上画的形状的信息
    const rects = [];// 静态的绘制数据
    const imgCvs = options.imgCvs;
    const imgCtx = imgCvs.getContext('2d');
    const bitmap = options.bitmap;
    const oprCvs = options.oprCvs;
    const oprCtx = oprCvs.getContext('2d');
    const canvasWidth = imgCtx.width;
    const canvasHeight = imgCtx.height;
  //  绘制图像
  this.drawBitmap = (mbitmap = bitmap) => {
    imgCtx.drawImage(mbitmap, 0 ,0, imgCvs.width, imgCvs.height);
  };
// 鼠标相对于画布的真实位置和画布的偏移 画布的缩放相关进行更新改造
const getCanvasPosition = (e, offset = { x: 0, y:0 }, scale = 1) => {
  return {
    x:(e.offsetX  - offset.x) / scale,
    y: (e.offsetY - offset.y) /scale,
  }
}
// 鼠标的位置
const getMousePosition = e => {
  return {
    x: e.offsetX,
    y: e.offsetY,
  }
}
// 计算两个点之间的距离  判断移动的长度用于阈值判定
const getDistance = (p1, p2) => {
  return Math.sqrt((p1.x - p2.x) **2 + (p1.y - p2.y) ** 2);
}
// 判断某个位置是否在矩形中
const ifInRect = pos => {
  for(let i = 0 ; i < rects.length; i++) {
    let rect = rects[i];
    if(pos.x > rect.x && pos.x < ( rect.x + rect.w) && pos.y > rect.y && pos.y < (rect.y + rect.h)) {
      // return true;
      // 需要知道是哪一个形状
      return rect;
    }
  }
  return false;
}
// 滚轮事件监听 调整缩放
oprCvs.addEventListener('wheel', e => {
  e.preventDefault();// 阻止默认的滚轮事件
  const canvasPosition = getCanvasPosition(e, canvasInfo.offset);
  const { scaleStep, maxScale, minScale } = canvasInfo
  // 计算缩放时产生的新的偏移量
  const deltaX = canvasPosition.x / canvasInfo.scale * scaleStep;
  const deltaY = canvasPosition.y / canvasInfo.scale * scaleStep;
  console.log('canvasInfo.scale', canvasInfo.scale)
  if(e.wheelDelta > 0 && canvasInfo.scale < maxScale) {
    console.log('放大')
    canvasInfo.offset.x -= deltaX;
    canvasInfo.offset.y -= deltaY;
    canvasInfo.scale += scaleStep;
  } else if(e.wheelDelta <= 0 && canvasInfo.scale > minScale) {
    console.log('缩小')
    // if(canvasInfo.scale - scaleStep < minScale) {
    //   console.log('小于小于小于');
    //   console.log((canvasInfo.scale - minScale))
    //   const deltaXx = canvasPosition.x / canvasInfo.scale * (canvasInfo.scale - minScale);
    //   const deltaYy = canvasPosition.y / canvasInfo.scale * (canvasInfo.scale - minScale);
    //   canvasInfo.offset.x += deltaXx;
    //   canvasInfo.offset.y += deltaYy;
    //   canvasInfo.scale = minScale;
    // } else 
    {
      canvasInfo.offset.x += deltaX;
      canvasInfo.offset.y += deltaY;
      canvasInfo.scale -= scaleStep;
    }
  }
  // 重新渲染
  render()
})

// 鼠标事件 图形绘制和画布拖拽
oprCvs.addEventListener('mousedown', e => {
  const canvasPosition = getCanvasPosition(e,canvasInfo.offset,canvasInfo.scale);
  if(canvasInfo.openDraw) {
    canvasInfo.status = statusConfig.DRAG_START;
    canvasInfo.lastEvtPos = canvasPosition;
    canvasInfo.offsetEvtPos = canvasPosition;
  } else {
    // 默认按下进行画布拖拽
    canvasInfo.status = statusConfig.MOVE_START;
    canvasInfo.offseteMouseEvtPos = getMousePosition(e);
  }
});

// 鼠标移动
oprCvs.addEventListener('mousemove', e => {
  const { DRAG_START, DRAGING, MOVE_START, MOVING } = statusConfig;
  const { status, lastEvtPos }  = canvasInfo;
  const canvasPosition = getCanvasPosition(e,canvasInfo.offset, canvasInfo.scale);
  if(canvasInfo.openDraw) {
    oprCvs.style.cursor = 'crosshair';
  } else {
    oprCvs.style.cursor = '';
  }
  // dragStargt
  if(status === DRAG_START && getDistance(lastEvtPos, canvasPosition) > 5) {
    canvasInfo.status = DRAGING;
    canvasInfo.offsetEvtPos = canvasPosition; 
    canvasInfo.dynamicInfo.x = canvasPosition.x;
    canvasInfo.dynamicInfo.y = canvasPosition.y;
    canvasInfo.dynamicInfo.w = 0;
    canvasInfo.dynamicInfo.h = 0;
  } else if(status == DRAGING) {
    if(canvasInfo.openDraw) {
      canvasInfo.dynamicInfo.w += canvasPosition.x - canvasInfo.offsetEvtPos.x;
      canvasInfo.dynamicInfo.h += canvasPosition.y - canvasInfo.offsetEvtPos.y;
      render()
    }
    canvasInfo.offsetEvtPos = canvasPosition;
  } else if(status === MOVE_START && getDistance(canvasPosition,lastEvtPos) > 5) {
    // 开始拖拽画布
    canvasInfo.status = MOVING;
    canvasInfo.offseteMouseEvtPos = getMousePosition(e);
  } else if(status === MOVING) {
    let mousePosition = getMousePosition(e);
    canvasInfo.offset.x += mousePosition.x - canvasInfo.offseteMouseEvtPos.x;
    canvasInfo.offset.y += mousePosition.y - canvasInfo.offseteMouseEvtPos.y;
    render();
    canvasInfo.offseteMouseEvtPos = mousePosition;
  }
})
// 鼠标抬起
oprCvs.addEventListener('mouseup', e => {
  const { IDLE, DRAG_START, DRAGING, MOVE_START, MOVING } = statusConfig
  if(canvasInfo.status === DRAGING || canvasInfo.status === DRAG_START ||  canvasInfo.status === MOVE_START||canvasInfo.status ===MOVING) {
    canvasInfo.status = IDLE;// 恢复鼠标闲置状态
    console.log('结束')
  }
})
// 绘制矩形 需要开始点坐标x y 矩形宽高 w h
const drawRect = (ctx, x, y, w, h) => {
  ctx.save();
  ctx.beginPath();
  ctx.strokeStyle = 'red';
  ctx.lineWidth = 2;
  ctx.rect(x ,y ,w,h);
  ctx.stroke();
  ctx.closePath();// 自动闭合至结束路径
  ctx.restore();
}
//  缩放移动等需要重绘的逻辑
const render = () => {
  oprCtx.clearRect(0, 0, oprCvs.width, oprCvs.height);
  oprCtx.setTransform(canvasInfo.scale, 0, 0, canvasInfo.scale, canvasInfo.offset.x,canvasInfo.offset.y);
  rects.forEach(r => drawRect(oprCtx,r.x, r.y, r.w, r.h))
  if(canvasInfo.openDraw) {
    const {x, y, w, h} = canvasInfo.dynamicInfo
    console.log(canvasInfo.dynamicInfo)
    drawRect(oprCtx, x, y, w, h);
  }

  // 重绘图片
  imgCtx.clearRect(0, 0,imgCvs.width, imgCvs.height);
  imgCtx.setTransform(canvasInfo.scale, 0, 0, canvasInfo.scale, canvasInfo.offset.x,canvasInfo.offset.y);
  imgCtx.drawImage(bitmap, 0, 0, imgCvs.width, imgCvs.height)
}
 // 绘制两个静态框
 drawRect(oprCtx,30,30, 100, 100);
 rects.push({x:30,y:30,w:100,h:100});
 // 画完形状后将形状信息进行存储
 drawRect(oprCtx, 180, 180, 200, 100,)
 rects.push({x:180,y:180,w:200,h:100})
// 开始手动绘制
this.openDraw = e => {
  console.log('开启绘制');
  canvasInfo.openDraw = true;
  oprCvs.style.cursor = 'crosshair'
}
// 关闭手动绘制
this.closeDraw = e => {
  console.log('关闭绘制');
  canvasInfo.openDraw = false;
  oprCvs.style.cursor = '';
  // canvasInfo.dynamicInfo = { x: 0, y: 0, w: 0, h:0 }
  render()
}
}